#include "quadtree.h"

#include <iostream>

int Quadtree::nbDeleteQuadtree = 0;

Quadtree::~Quadtree()
{
        std::vector<Node*>::iterator it;
        for (it = allNode.begin(); it != allNode.end(); )
        {
                delete(*it);
                it = allNode.erase(it);
        }

        nbDeleteQuadtree++;
        std::cout << "Nombre de Quadtree détruit : " << nbDeleteQuadtree << std::endl;
}

void Quadtree::AddNode(Node *ancestor)
{
        int x1 = ancestor->GetTlX();
        int y1 = ancestor->GetTlY();
        int x2 = ancestor->GetBrX();
        int y2 = ancestor->GetBrY();
        int x12 = (x2 - x1) / 2 + x1;
        int y12 = (y2 - y1) / 2 + y1;
        int level = ancestor->GetNodeLevel() + 1;

        Node *leaf1 = new Node(x1, y1, x12, y12, level, ancestor);
        Node *leaf2 = new Node(x12 + 1, y1, x2, y12, level, ancestor);
        Node *leaf3 = new Node(x1, y12 + 1, x12, y2, level, ancestor);
        Node *leaf4 = new Node(x12 + 1, y12 + 1, x2, y2, level, ancestor);

        if (leaf1 == NULL)
                std::cout << "leaf1 NULL" << std::endl;

        if (leaf2 == NULL)
                std::cout << "leaf2 NULL" << std::endl;

        if (leaf3 == NULL)
                std::cout << "leaf3 NULL" << std::endl;

        if (leaf4 == NULL)
                std::cout << "leaf4 NULL" << std::endl;

        leaf1->InheritAdjacentMatrixTop(ancestor->ReturnAdjacentMatrixTop());
        leaf1->AddNeighbourRight(leaf2);
        leaf1->AddNeighbourBottom(leaf3);
        leaf1->InheritAdjacentMatrixLeft(ancestor->ReturnAdjacentMatrixLeft());

        leaf2->InheritAdjacentMatrixTop(ancestor->ReturnAdjacentMatrixTop(), false);
        leaf2->InheritAdjacentMatrixRight(ancestor->ReturnAdjacentMatrixRight());
        leaf2->AddNeighbourBottom(leaf4);
        leaf2->AddNeighbourLeft(leaf1);

        leaf3->AddNeighbourTop(leaf1);
        leaf3->AddNeighbourRight(leaf4);
        leaf3->InheritAdjacentMatrixBottom(ancestor->ReturnAdjacentMatrixBottom());
        leaf3->InheritAdjacentMatrixLeft(ancestor->ReturnAdjacentMatrixLeft(), false);

        leaf4->AddNeighbourTop(leaf2);
        leaf4->InheritAdjacentMatrixRight(ancestor->ReturnAdjacentMatrixRight(), false);
        leaf4->InheritAdjacentMatrixBottom(ancestor->ReturnAdjacentMatrixBottom(), false);
        leaf4->AddNeighbourLeft(leaf3);

        ancestor->RemoveAdjacentMatrix();
        ancestor->SetColored(true);

        allNode.push_back(leaf1);
        allNode.push_back(leaf2);
        allNode.push_back(leaf3);
        allNode.push_back(leaf4);
}

void Quadtree::Display(IplImage *img)
{
        CvScalar pixel;
        pixel.val[1] = 255;

        std::vector<Node*>::const_iterator it;
        for (it = allNode.begin(); it != allNode.end(); it++)
        {
                for (int i = (*it)->GetTlX() ; i <= (*it)->GetBrX(); i++)
                {
                        for (int j = (*it)->GetTlY() ; j <= (*it)->GetBrY() ; j++)
                        {
                                if (i == (*it)->GetTlX() || j == (*it)->GetTlY())
                                        cvSet2D(img, j, i, pixel);
                        }
                }
        }
}

void Quadtree::Display()
{
        int i = 0;
        std::vector<Node*>::const_iterator it;
        for (it = allNode.begin(); it != allNode.end(); ++it)
        {
                std::cout << "Noeud " << i << " : " << std::endl;
                std::cout << "tl_x : " << (*it)->GetTlX() << " , tl_y : " << (*it)->GetTlY() << std::endl;
                std::cout << "br_x : " << (*it)->GetBrX() << " , br_y : " << (*it)->GetBrY() << std::endl;
                std::cout << "level : " << (*it)->GetNodeLevel() << std::endl << std::endl;
                ++i;
        }
}


void Quadtree::Display(Node *node)
{
        std::cout << "tl_x : " << node->GetTlX() << " , tl_y : " << node->GetTlY() << std::endl;
        std::cout << "br_x : " << node->GetBrX() << " , br_y : " << node->GetBrY() << std::endl;
        std::cout << "level : " << node->GetNodeLevel() << std::endl << std::endl;
}





